local LogDefine = require("common.LogDefine")
local Util = require("common.Util")
local Log = require("common.Log")
local Lang= require("common.Lang")
local Msg = require("core.Msg")
local CommonDefine = require("common.CommonDefine")
local RoleFFI  = require("role.RoleFFI")
local Status = require("scene.Status")
local Obj = require("core.Obj")
local RoleDefine = require("role.RoleDefine")
local ExcelMap = require("excel.Map")
local Map = require("core.Map")
local Timer = require("core.Timer")
local Skill = require("skill.Skill")
local RoleExcel   = require("excel.Role")
local RoleBaseAttr = RoleExcel.baseAttr
local CombatCalc = require("skill.CombatCalc")
local RoleAttr = require("role.RoleAttr")
local SkillConfig = require("excel.Skill").Skill
local ExcelMonster = require("excel.Monster")
local SceneEvent = require("core.SceneEvent")
local Buffer = require("buffer.Buffer")
local BufferNotify = require("buffer.Notify")
local FcmLogic = require("fcm.FcmLogic")
local Broadcast = require("broadcast.Broadcast")
local exp_conf = RoleExcel.exp
local BaseAttrInitValue = RoleExcel.baseAttrInitValue[1]
local ItemDefine = require("bag.ItemDefine")
local Copy = require("copy.CopyL")
local RoleUIControl = require("role.RoleUIControl")
local EquipConf = require("excel.Equip").equip
local sbConfig = require("excel.Shenbing").shenbing
local Cmds = require("buffer.Cmds")
local ShenbingLogic = require("shenbing.ShenbingLogic")
local TaskLogic = require("task.TaskLogic")
local CopyCallback = require("copy.CallbackL")
local ObjMonster = require("core.ObjMonster")
local HorseLogic = require("horse.HorseLogic")
local InnerDataManager = require("innerdata.InnerDataManagerFL")
local InnerDataDefine = require("innerdata.Define")
local ExcelMapConf = require("excel.Map")
local ObjPet = require("core.ObjPet")
local RoleCombatMode = require("role.RoleCombatMode")
local fuliHandler = require("fuli.HandlerL")
local MonthCardLogic = require("vip.MonthCardLogic")
local SmeltLogic = require("bag.SmeltLogic")
local MySteryShop = require("shop.MySteryShop")
local BagHandlerL = require("bag.HandlerL")
local FirstPayLogic = require("fuli.FirstPayLogic")
local WushuangCopy = require("copy.Wushuang")
local FamilyHandlerL = require("family.HandlerL")
local FamilyLogicFL = require("family.FamilyLogicFL")
local PetLogic = require("pet.PetLogic")
local PetAi = require("pet.PetAi")
local AcvityDefine = require("activity.Define")
local ShopLogic = require("shop.ShopLogic")
local SceneHandler = require("scene.HandlerL")
local YellowLogic = require("yellow.YellowLogic")
local TGPLogic = require("yellow.TGPLogic")
local HorseExcel = require("excel.Horse")
local CopyDefine = require("copy.Define")
local RefineHandlerL = require("refine.HandlerL")
local HtmlUtil = require("common.HtmlUtil")
local BaowuLogic = require("baowu.BaowuLogic")
local OperateActLogicL = require("activity.operate.OperateActLogicL")
local Config = require("Config")
local ChongzhiDraw = require("activity.operate.ChongzhiDraw")
local CritDraw = require("activity.operate.CritDraw")
local PayDraw = require("activity.operate.PayDraw")
local FindResLogic = require("findRes.FindResLogic")
local BlueLogic = require("yellow.BlueLogic")
local PfLogic = require("tencentApi.PfLogic")
local DateActFL = require("activity.DateActFL")
local DateLimitBuy = require("activity.date.LimitBuy")
local DailyGift = require("activity.operate.DailyGift")
local ArmourDefine = require("armour.Define")
local TitleLogic = require("title.TitleLogic")
local OfficialLogic = require("official.OfficialLogic")

local logic_id = _G.logic_id


onlineHuman = onlineHuman or {}
onlineAccount = onlineAccount or {}
onlineUuid = onlineUuid or {}

fds = fds or {}		--fd转换成obj_id

function sendAttr(human,key)
    local msgRet = Msg.gc.GC_ROLE_ATTR
    msgRet.attrs[0] = 1
    local attr = msgRet.attrs[1]
    attr.key = key
    attr.value = human.attr[key]
    Msg.send(msgRet, human.fd)
end

function create(fd, account, db, id, uid, login)
    local human = {}
    Obj.create(human, Obj.TYPE_HUMAN, id, uid)
    fds[fd] = human.id
    human.fd = fd

    human.attr = {}												  -- 人物属性缓存
    human.killMonsterExpAdd= nil					  -- 杀怪经验增加
    human.killCount = 0											-- 连杀数
    human.killLastTime = 0									-- 连杀上次时间
    human.path_len = 0
    human.path_time = nil
    human.path_client_x = nil
    human.path_client_y = nil
    human.grid_rebuy = {}                    --出售商品列表
    human.fcTmp = {}                        --寻宝临时参数
    human.addTempWW = 0                     --荆州争夺战临时增加的威望值
    human.jingzhouKillCnt = 0               --荆州争夺战击杀数
    human.datiRightCnt = 0                  --答题活动正确答题数量
    human.datiTotalAddExp = 0                    --答题累计获得经验值

    human.db = db

    --小优化
    human._id = RoleFFI.ffi_string(human.db._id)
    human.account = RoleFFI.ffi_string(human.db.account)
    human.name = RoleFFI.ffi_string(human.db.name)
    human.ip   = RoleFFI.ffi_string(human.db.ip)
    human.familyUuid = RoleFFI.ffi_string(human.db.familyUuid)
    human.familyName = RoleFFI.ffi_string(human.db.familyName)
    human.pf = RoleFFI.ffi_string(human.db.pf)
    human.familyUuidM = RoleFFI.ffi_string(human.db.familyUuidM)

    human.status = Status.HUMAN_STATUS_NORMAL
    human.db.status = human.status
    human.camps = 0
    human.laskSkillTime = nil      -- 最近一次打人
    human.laskBeHitTime = nil      -- 最近一次被人打
    
    human.maxFinishMainTask = nil  --玩家历史完成过的最大的主线任务
    human.maxDoingMainTask = nil   --玩家正在做的最大的主线任务

    local preLastLoginTime = human.db.lastLoginTime

    if Util.isSameDay(preLastLoginTime) then
        human.dailyFirstLogin = false							-- 是否每天首次登录
    else
        human.dailyFirstLogin = true
    end


    Buffer.init(human, login)
    Skill.init(human)

    CombatCalc.initAttr(human)




    onlineHuman[human.name] = human
    onlineAccount[human.account] = human
    onlineUuid[human._id] = human
    
    -- doCalc
    RoleAttr.doCalc(human)
    return human
end

--生成临时human结构，不进场景
function create_human(db)
    local human = {}
    human.db = db
    human.attr = {}                         -- 人物属性缓存
    human.obj_type = Obj.TYPE_HUMAN
    Buffer.init(human)
    Skill.init(human)
    CombatCalc.initAttr(human)
     -- doCalc
    RoleAttr.doCalc(human)
    return human
end

function destroy(human)
    if human.fd then fds[human.fd] = nil end
    onlineHuman[human.name] = nil
    onlineAccount[human.account] = nil
    onlineUuid[human._id] = nil
    Obj.destroy(human)
end

function doDisconnect(human, code)
    print("L disconnect name:", human.name, " code:", code)

    local now = os.time()
    local map_id = Map.scene_id_to_map_id[human.scene_id]
    Log.write(Log.LOGID_OSS_LOGOUT, human._id, human.account, human.name, human.db.lv, human.ip, code, map_id, human.x, human.y, now - human.db.lastLoginTime)

    if code ~= CommonDefine.DISCONNECT_NORMAL then
        if human.x and human.y then
            human.db.x = human.x
            human.db.y = human.y
        end   
        if human.fd then  
            onLoginOut(human) --非正常退出，就走这里了
        end
        destroy(human)
        local msg = Msg.lw.LW_AA_DISCONNECT  --通知world 消除		msg.objid = human.id
        msg.account = human.account
        msg.objid = human.id
        msg.code = code
        Msg.send2world(msg, "")
        return
    end

    if not human.fd then
        assert()
    end
    fds[human.fd] = nil
    if Obj.scenes_fds[human.scene_id] then
        Obj.scenes_fds[human.scene_id][human.fd] = nil
    end
    human.fd = nil
    human.f5 = Timer.now    
    onLoginOut(human)
end

-- 退出时回调
function onLoginOut(human)
--    human.db.lastLogoutTime = os.time() --记录最近登出时间
    FcmLogic.onLogout(human)    
    Buffer.humanDestroy(human)
end



function humanOfflineCheck()
    for name, human in pairs(onlineHuman) do
        if human.fd == nil then
            if human.f5 == nil or Timer.now - human.f5 > 120000 then
                doDisconnect(human, CommonDefine.DISCONNECT_NORMAL_AFTER, "")
            end
        end
    end
end

function getObjAdd(human)
    local mm = Msg.gc.GC_ADD_PLAYER
    mm.obj_id = human.id
    mm.uuid = human._id
    mm.name = human.name
    mm.familyUuid = human.familyUuid
    mm.familyName = human.familyName
    mm.allyName =""
    mm.status = Cmds.passive.giddy(human)==1 and Status.HUMAN_STATUS_GIDDY or human.status or 1
    mm.head = human.db.head
    Status.makeViewInfo(mm.viewInfo, human.db.sex, Obj.getBodyInfo(human))
    mm.x = human.x
    mm.y = human.y
    mm.speed = human.speed
    mm.dir = human.dir
    mm.points[0] = human.path_len * 2
    for i = 1, human.path_len do
        local j = human.path_len + 1 - i
        mm.points[2 * i - 1] = human.path[2 * j - 1]
        mm.points[2 * i] = human.path[2 * j]
    end
    BufferNotify.setBufferInfo(human, mm.bufInfo)
    mm.hp = human.db.hp
    mm.hpMax = getHpMax(human)
    mm.mp = human.db.mp
    mm.mpMax = getMpMax(human)
    mm.sex = human.db.sex
    mm.lv = human.db.lv
    mm.title = TitleLogic.getTitle(human)
    
    mm.combatMode = RoleCombatMode.getCombatMode(human)
    mm.combatSide = RoleCombatMode.getCombatSide(human)
    mm.awakeColor = sbConfig[human.db.putonShenbing] and sbConfig[human.db.putonShenbing].awakeColor or 0
    if PfLogic.isYellowShow(human) then
      mm.yellowVipLv = human.db.yellowVipLv
      mm.yellowYearVip = human.db.yellowYearVip
    else  
      mm.yellowVipLv = 0
      mm.yellowYearVip = 0
    end
    if PfLogic.isBlueShow(human) then
      mm.blueVipLv = human.db.blueVipLv
      mm.blueYearVip = human.db.blueYearVip
      mm.blueSuperVip = human.db.blueSuperVip
      mm.level3366 = human.db.level3366
    else
      mm.blueVipLv = 0
      mm.blueYearVip = 0
      mm.blueSuperVip = 0
      mm.level3366 = 0
    end  
    mm.tgpInfo = human.db.isMiniClient
    return mm
end

function enterMap(human, mapID, x, y)
    print("enter map ", mapID)
    if human.status == Status.HUMAN_STATUS_OBSERVER then
        Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_NORMAL)
    end

    local cf = ExcelMap.scene[mapID]
    if not x then
        x = cf.x
        y = cf.y
    end
    local copyID = Copy.isCopy(mapID)
    if copyID and cf.logic_id ~= logic_id then
        assert(nil)
    end
    local oldSceneID = human.scene_id
    if mapID == Map.HOME_MAP_ID1 then
        human.db.reviveNowItemNum = 0
    end
    Obj.leaveScene(human)
    local sceneID = Map.map_id_to_scene_id[mapID][1]
    if copyID then
        local mapCheckID, sceneCheckID, checkX, checkY = Copy.checkEnter(human, mapID, x, y)
        print("mapCheckID:"..mapCheckID.." sceneCheck:",sceneCheckID, " cx:"..checkX.." cy:"..checkY)
        if mapID ~= mapCheckID then
            enterMap(human, mapCheckID, checkX, checkY)
            return
        end
        sceneID = sceneCheckID

        if (oldSceneID and (not Copy.isCopyBySceneID(oldSceneID))) or ((not oldSceneID) and (not Copy.isCopy(human.db.map_id)))  then
            local oldMapID = oldSceneID and Map.scene_id_to_map_id[oldSceneID]
            if oldMapID then
                human.db.copyEnterMap = oldMapID
                human.db.copyEnterX = human.x
                human.db.copyEnterY = human.y
            else
                human.db.copyEnterMap = human.db.map_id
                human.db.copyEnterX = human.db.x
                human.db.copyEnterY = human.db.y
            end
        end
    elseif Config.IS_MIDDLE then 
        local oldMapID = oldSceneID and Map.scene_id_to_map_id[oldSceneID]
        if oldMapID and Copy.isCopy(oldMapID) then --跨服从副本退出,直接退回本服
            if human.fd == nil then
                return
            end
            destroy(human)
            local msg = Msg.lw.LW_ASK_CHANGE_SCENE
            msg.map_id = mapID
            msg.x = x
            msg.y = y
            msg.middle = 1
            Msg.send2world(msg, human._id)
            return
        end
    end
    
    if Config.IS_MIDDLE and not Copy.isCopy(mapID) then  --不能进普通场景，如果进普通场景直接退回本服
            if human.fd == nil then
                return
            end
            destroy(human)
            local msg = Msg.lw.LW_ASK_CHANGE_SCENE
            msg.map_id = mapID
            msg.x = x
            msg.y = y
            msg.middle = 1
            Msg.send2world(msg, human._id)
            return
    end

    if cf.logic_id ~= logic_id then
        if human.fd == nil then  --已断线的情况，不要再跑下面了。
            return
        end
        --跨线程
        destroy(human)
        local msg = Msg.lw.LW_ASK_CHANGE_SCENE
        msg.map_id = mapID
        msg.x = x
        msg.y = y
        msg.middle = 0
        Msg.send2world(msg, human._id)
        return
    end

    if copyID == nil then
        human.db.preMapID = human.db.map_id
        human.db.preMapX = human.db.x
        human.db.preMapY = human.db.y
    end

    human.db.map_id = mapID
    human.db.x = x
    human.db.y = y

    human.hide = 1
    Obj.enterScene(human, sceneID, x, y)

    local mapConfig = ExcelMap.scene[mapID]
    local mm = Msg.gc.GC_ENTER_SCENE
    mm.map_id = human.db.map_id
    mm.x = x
    mm.y = y
    mm.map_jpg = mapConfig.map_jpg
    if copyID == nil then
        mm.copy_type = 0
        mm.difficult = 0
    else
        mm.copy_type = ExcelMap.copy[copyID].type
        mm.difficult = ExcelMap.copy[copyID].difficult
    end
    mm.isPVP = mapConfig.isPVP
    mm.mapType = mapConfig.mapType

    local loadList = mapConfig.loadList

    for i=1,#loadList do
        local LoadFileInfo = mm.loadList[i]
        local info = loadList[i]
        LoadFileInfo.type = info[1]
        LoadFileInfo.url = tostring(info[2])
    end

    mm.loadList[0] = #loadList

	if mm.map_id == 1001 then
		local loadCnt = mm.loadList[0]
		mm.loadList[0] = loadCnt + 2
		mm.loadList[loadCnt + 1].type = 5
		mm.loadList[loadCnt + 2].type = 5
		if human.db.sex == 1 then
			mm.loadList[loadCnt + 1].url = "resource/role/role/body/bodyid/1.bin"
			mm.loadList[loadCnt + 2].url = "resource/role/role/body/animation/1.bin"
		else
			mm.loadList[loadCnt + 1].url = "resource/role/role/body/bodyid/2.bin"
			mm.loadList[loadCnt + 2].url = "resource/role/role/body/animation/2.bin"
		end
	end

    Msg.send(mm, human.fd)

    ObjPet.callPet(human)
    
    if human.isLogin then
        SceneHandler.onUserLogin(human)
        human.isLogin = nil
    end
end



function setHp(human, hp,noSend)
    local hpMax = math.floor(getHpMax(human))
    hp = math.floor(hp)
    hp = math.max(0, hp)
    hp = math.min(hp, hpMax)
    if human.db.hp == hp then
        return
    end
    if human.wudi and hp < 1 then
        hp = hpMax
    end
    
    human.db.hp = hp
    human.attr[RoleDefine.HP] = hp
    if human.db.teamUuidLen > 0 then
        InnerDataManager.Send2WInnerData(human, InnerDataDefine.INNERDATA_TYPE_HPCHANGE, nil)
    end

    if not noSend then
        sendAttr(human,RoleDefine.HP)
    end
end

function getHp(human)
    local t = math.floor(human.db.hp)
    if t ~= human.db.hp then
        assert()
    end
    return t
end

function getHpMax(human)
    local t = math.floor(human.attr[RoleDefine.HP_MAX])
    if t ~= human.attr[RoleDefine.HP_MAX] then
        human.attr[RoleDefine.HP_MAX] = t
        assert()
    end
    human.db.MaxHp = human.attr[RoleDefine.HP_MAX]
    return t
end

function setMp(human, mp,noSend)
    mp = math.max(0, mp)
    mp = math.min(mp, getMpMax(human))
    mp = math.floor(mp)
    if human.db.mp == mp then
        return
    end
    human.db.mp = mp
    human.attr[RoleDefine.MP] = mp
    if not noSend then
        sendAttr(human,RoleDefine.MP)
    end

end

function getMpMax(human)
    local t = math.floor(human.attr[RoleDefine.MP_MAX])
    if t ~= human.attr[RoleDefine.MP_MAX] then
        assert()
    end
    human.db.MaxMp = human.attr[RoleDefine.MP_MAX]
    return t
end

function getEquipTotalPower(human)
    local power = 0
    for i=0,human.db.equipLen - 1 do
        local grid = human.db.equip[i]
        if grid ~= nil and grid.id ~= 0 then
          power = power + (grid.data.equip.power or 0)
        end
    end
    return power
  end

local maxYinliang = 2100000000	--21亿
function canUpdateYinliang(human,d)
    d = math.floor(d)
    if d == 0 then
        return true
    end
    if d > 0 then d = FcmLogic.handleYinliang(human, d) end
    local val = human.db.yinliang + d
    if val < 0 then
        return
    end
    if val > maxYinliang then
        return
    end
    return true
end

function getYinliang(human)
    return human.db.yinliang - human.db.precost_yinliang
end

function canAddYinliang(human,d)
    d = math.floor(d)
    if d > 0 then d = FcmLogic.handleYinliang(human, d) end
    if d == 0 then
        return
    end
    local val = human.db.yinliang + d
    if val < 0 then
        return
    end
    if val > maxYinliang then
        return
    end
    return true
end

function canAddZhanGong(human, oSum)
    --返回-1代表无法增加战功，1表示在该等级段本次战功增加完后下次还可以继续进行战功增加 2表示本次增加完后就无法再增加战功了 oSum字段表示累计增加战功总数
    --该功能为方便连续性的战功增加功能逻辑判断
    if oSum then
        if RoleBaseAttr[human.db.lv] and human.attr[RoleDefine.ZHANGONG_MAX] and (human.db.zhangong < human.attr[RoleDefine.ZHANGONG_MAX]
            and ((human.db.zhangong + oSum) < human.attr[RoleDefine.ZHANGONG_MAX])) then
            if human.db.zhangong + oSum >= RoleBaseAttr[human.db.lv].maxZhangong then
                return 2
            end
            return 1 
        end
    else
        if RoleBaseAttr[human.db.lv] and RoleBaseAttr[human.db.lv].maxZhangong and (human.db.zhangong < RoleBaseAttr[human.db.lv].maxZhangong)  then
            if human.db.zhangong + oSum >= RoleBaseAttr[human.db.lv].maxZhangong then
                return 2
            end
            return 1 
        end
    end
    return -1 
end

function canAddAwake(human)
    return human.db.awakeVal >= 0 and human.db.awakeVal < 1000 
end

function addYinliang(human,d,logType,item_id, num)
    if not LogDefine.DEFINE[logType] then
        assert()
    end
    d = math.floor(d)
    if d > 0 then d = FcmLogic.handleYinliang(human, d) end
    if d == 0 then
        return
    end
    if d < 0 then
        assert()
    end
    local val = human.db.yinliang + d

    if val > maxYinliang then
        val = maxYinliang
        Broadcast.sendBroadcast(human, Lang.CHAT, Lang.COMMON_ADD_YINLIANG_LIMIT)
    end

    --铜币使用日志
    if item_id == nil then item_id = 0 end
    if num == nil then num = 0 end
    Log.write(Log.LOGID_OSS_YILIANG, human._id, human.account, human.name, human.db.lv, d, LogDefine.DEFINE[logType] + LogDefine.TYPE["yinliang"], item_id, num, val)
    human.db.yinliang = val
    human.attr[RoleDefine.YINLIANG] = human.db.yinliang
    sendAttr(human,RoleDefine.YINLIANG)
    RefineHandlerL.CG_OPEN_REFINE_WINDOW(human)
    return true
end

function decYinliang(human,d,logType,item_id, num)
    d = math.floor(d)
    if d == 0 then
        return
    end
    if not LogDefine.DEFINE[logType] then
        assert()
    end
    if d < 0 then
        assert()
    end
    local sum = human.db.yinliang
    local nowYinliang = sum - d
    if nowYinliang < 0 then
        assert()
    end

    if item_id == nil then item_id = 0 end
    if num == nil then num = 0 end
    --银两使用日志
    Log.write(Log.LOGID_OSS_YILIANG, human._id, human.account, human.name, human.db.lv, -d, LogDefine.DEFINE[logType] + LogDefine.TYPE["yinliang"], item_id, num, nowYinliang)
    human.db.yinliang = nowYinliang
    human.attr[RoleDefine.YINLIANG] = human.db.yinliang
    sendAttr(human,RoleDefine.YINLIANG)
    return true
end

function getYuanbao(human)
    return human.db.yuanbao - human.db.precost_yuanbao
end

function addBindYuanbao(human, d, logType, item_id, num)
    d = math.floor(d)
    if d == 0 then
        return
    end
    if d < 0 then
        assert()
    end
    if not LogDefine.DEFINE[logType] then
        assert()
    end
    local val = human.db.bind_yuanbao + d
    if val > maxYinliang then
        val = maxYinliang
    end
    if item_id == nil then item_id = 0 end
    if num == nil then num = 0 end
    Log.write(Log.LOGID_OSS_GOLD, human._id, human.account, human.name, human.db.lv, d, LogDefine.DEFINE[logType] + LogDefine.TYPE["bind_yuanbao"] , item_id, num, val)
    human.db.bind_yuanbao = val
    human.attr[RoleDefine.BIND_YUANBAO] = human.db.bind_yuanbao
    sendAttr(human, RoleDefine.BIND_YUANBAO)
    return true
end
function addYuanbao(human, d, logType, item_id, num)
    d = math.floor(d)
    if d == 0 then
        return
    end
    if d < 0 then
        assert()
    end
    if not LogDefine.DEFINE[logType] then
        assert()
    end
    local val = human.db.yuanbao + d
    if val > maxYinliang then
        val = maxYinliang
    end
    if item_id == nil then item_id = 0 end
    if num == nil then num = 0 end
    Log.write(Log.LOGID_OSS_GOLD, human._id, human.account, human.name, human.db.lv, d, LogDefine.DEFINE[logType] + LogDefine.TYPE["yuanbao"] , item_id, num, val)
    human.db.yuanbao = val
    human.attr[RoleDefine.YUANBAO] = human.db.yuanbao
    sendAttr(human, RoleDefine.YUANBAO)
    return true
end

function decYuanbao(human, d, logType, item_id, num)
    d = math.floor(d)
    if d == 0 then
        return
    end
    if d < 0 then
        assert()
    end

    if not LogDefine.DEFINE[logType] then
        assert()
    end
    if human.db.yuanbao < d then
        assert()
    end

    item_id = item_id or 0
    num = num or 0
    local val = human.db.yuanbao - d

    Log.write(Log.LOGID_OSS_GOLD, human._id, human.account, human.name, human.db.lv, -d, LogDefine.DEFINE[logType] + LogDefine.TYPE["yuanbao"] , item_id, num, val)
    human.db.dailyCostYuanbao = human.db.dailyCostYuanbao + d
    human.attr[RoleDefine.DAILY_COST_YUANBAO] = human.db.dailyCostYuanbao
    sendAttr(human, RoleDefine.DAILY_COST_YUANBAO) 
    human.db.yuanbao = val    
    human.attr[RoleDefine.YUANBAO] = human.db.yuanbao
    sendAttr(human, RoleDefine.YUANBAO)
    PayDraw.open(human, AcvityDefine.OPERATEACT_TYPE_PAYDRAW)
end

function getBindYuanbao(human)
    return human.db.bind_yuanbao
end

function decBindYuanbao(human, d, logType, item_id, num)
    d = math.floor(d)
    if d == 0 then
        return
    end
    if d < 0 then
        assert()
    end

    if not LogDefine.DEFINE[logType] then
        assert()
    end
    if human.db.bind_yuanbao < d then
        assert()
    end
    item_id = item_id or 0
    num = num or 0
    local val = human.db.bind_yuanbao - d

    Log.write(Log.LOGID_OSS_GOLD, human._id, human.account, human.name, human.db.lv, -d, LogDefine.DEFINE[logType] + LogDefine.TYPE["bind_yuanbao"] , item_id, num, val)
    human.db.bind_yuanbao = val
    human.db.dailyCostBindYunabao = human.db.dailyCostBindYunabao + d
    human.attr[RoleDefine.BIND_YUANBAO] = human.db.bind_yuanbao
    sendAttr(human, RoleDefine.BIND_YUANBAO)
end

function checkYuanbaoEnough(human, need_yuanbao)
    return human.db.yuanbao >= need_yuanbao
end

function getZhangong(human)
    return human.db.zhangong
end

function getRongyu(human)
    return human.db.rongyu
end

function getPrestige(human)
    return human.db.prestige
end

function decZhangong(human, cnt, logType, item_id, num)
    if human.db.zhangong - cnt < 0 then
        return false
    end
    if not logType then
      assert()
    end
    human.db.zhangong = human.db.zhangong - cnt
    human.attr[RoleDefine.ZHANGONG]  = human.db.zhangong
    sendAttr(human,RoleDefine.ZHANGONG)
    item_id = item_id or 0
    num = num or 0
    Log.write(Log.LOGID_OSS_ZHANGONG, human._id, human.account, human.name, human.db.lv, -cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["zhangong"] , item_id, num, human.db.zhangong)
    return true
end

function decRongyu(human, cnt, logType, item_id, num)
    if human.db.rongyu - cnt < 0 then
        return false
    end
    if not logType then
      assert()
    end
    human.db.rongyu = human.db.rongyu - cnt
    human.attr[RoleDefine.RONGYU] = human.db.rongyu
    sendAttr(human,RoleDefine.RONGYU)
    item_id = item_id or 0
    num = num or 0
    Log.write(Log.LOGID_OSS_HONOR, human._id, human.account, human.name, human.db.lv, -cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["honor"] , item_id, num, human.db.rongyu)
    return true
end

function decPrestige(human, cnt, logType, item_id, num)
    if human.db.prestige - cnt < 0 then
        return false
    end
    if not logType then
      assert()
    end
    human.db.prestige = human.db.prestige - cnt
    human.attr[RoleDefine.PRESTIGE] = human.db.prestige
    sendAttr(human,RoleDefine.PRESTIGE)
    item_id = item_id or 0
    num = num or 0
    Log.write(Log.LOGID_OSS_PRESTIGE, human._id, human.account, human.name, human.db.lv, -cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["prestige"] , item_id, num, human.db.prestige)
    return true
end

function addZhangong(human, cnt, logType, item_id, num)
   if cnt > 0 then cnt = FcmLogic.handleZhangong(human, cnt) end
   if cnt == 0 then
      return
   end
   if human.db.zhangong < human.attr[RoleDefine.ZHANGONG_MAX] then
        human.db.zhangong = human.db.zhangong + cnt
   else
        return false
   end
   if not logType then
      assert()
   end
    --该逻辑段注释原因为战功允许在没有达到最大上限时使用，而无论使用后的战功是否超过最大值
    --if human.db.zhangong + cnt > human.attr[RoleDefine.ZHANGONG_MAX] then
    --    cnt = human.attr[RoleDefine.ZHANGONG_MAX] - human.db.zhangong
    --    human.db.zhangong = human.attr[RoleDefine.ZHANGONG_MAX]
    --    if cnt <= 0 then
    --        return
    --    end
    --else
    --    human.db.zhangong = human.db.zhangong + cnt
    --end
    human.db.zhangongHistory = human.db.zhangongHistory + cnt
    human.attr[RoleDefine.ZHANGONG]  = human.db.zhangong
    human.attr[RoleDefine.ZHANGONG_HISTORY] = human.db.zhangongHistory
    sendAttr(human,RoleDefine.ZHANGONG_HISTORY)
    sendAttr(human,RoleDefine.ZHANGONG)
    item_id = item_id or 0
    num = num or 0
    OfficialLogic.checkOneCondition(human, "totalZhangong")    
    Log.write(Log.LOGID_OSS_ZHANGONG, human._id, human.account, human.name, human.db.lv, cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["zhangong"] , item_id, num, human.db.zhangong)
end

function addWushuang(human, cnt)
    human.db.wushuang = human.db.wushuang + cnt
end

function addPrestige(human, cnt)
    human.db.prestige = human.db.prestige + cnt
    human.attr[RoleDefine.PRESTIGE]  = human.db.prestige
    human.attr[RoleDefine.PRESTIGE_HISTORY] = human.db.prestigeHistory
    sendAttr(human,RoleDefine.PRESTIGE)
    sendAttr(human,RoleDefine.PRESTIGE_HISTORY)
end

function addRongyu(human, cnt)  --荣誉值
    human.db.rongyu = human.db.rongyu + cnt
    human.attr[RoleDefine.RONGYU] = human.db.rongyu
    sendAttr(human, RoleDefine.RONGYU)
end

function addJumpValue(human, cnt)
    if human.db.jumpValue >=  BaseAttrInitValue.jump_max then
        return
    end
    human.db.jumpValue = human.db.jumpValue +  cnt
    if human.db.jumpValue > BaseAttrInitValue.jump_max then
        human.db.jumpValue = BaseAttrInitValue.jump_max
    end
    human.attr[RoleDefine.JUMP_VALUE] = human.db.jumpValue
    sendAttr(human, RoleDefine.JUMP_VALUE)
end


function getBuf(human)
    return human.db.buf, human.db.bufLen
end
function setBufLen(human, len)
    human.db.bufLen = len
end

function getShenbing(human, id)
    for i = 0, human.db.shenbingLen - 1  do
        if human.db.shenbing[i].id == id then
            return human.db.shenbing[i]
        end
    end
end

function addShenbing(human, id, star)
    if getShenbing(human, id) ~= nil then
        return
    end
    local data = human.db.shenbing[human.db.shenbingLen]
    data.id = id
    data.lv = 0
    data.deng = 0
    data.jueji = 0
    data.star = star
    data.skillLv[0] = 1
    data.skillLv[1] = 1
    data.skillLv[2] = 0
    data.skillLv[3] = 0
    human.db.shenbingLen = human.db.shenbingLen + 1
    
    for i = 1, 8 do
        data.feedAttr[i-1] = 0
    end
end

function getPet(human, id)
    for i = 0, human.db.petLen -1 do
        if human.db.pet[i].id == id then
            return human.db.pet[i]
        end
    end
end

function addPet(human, id, star, skillCnt, lv, stage)
    if getPet(human, id) ~= nil then
        return
    end
    local data = human.db.pet[human.db.petLen]
    data.lv = lv or 1
    data.id = id
    data.status = 1
    data.star = star
    data.stage = stage or 1
    data.hp = 0x7fffffff
    for i=1, 4 do
      if i <= skillCnt then
        data.skillLv[i - 1] = 1
      else
        data.skillLv[i - 1] = 0
      end
    end
    for i=0, 3 do
      data.equipStatus[i] = 0
    end
    for i=0, 7 do
      data.feedAttrVal[i] = 0
    end
    data.zhandouli = 0
    data.next_create_time = 0
    data.startTime = 0
    data.limitTime = 0
    human.db.petLen = human.db.petLen + 1
    if human.db.petLen > 20 then
      human.db.petLen = 20
    end
    return data
end

function getBaowu(human, id)
  for i = 0, human.db.baowuLen -1 do
    if human.db.baowu[i].id == id then
      return human.db.baowu[i]
    end
  end
end
function addBaowu(human, id, skillId)
  if getBaowu(human, id) or not id then
    return
  end
  local data = human.db.baowu[human.db.baowuLen]
  data.id = id
  data.lv = lv or 0
  data.starLv = starLv or 0
  data.skillLv = skillLv or 1
  data.exp = 0
  data.status = 1
  data.power = 0
  data.skillId = skillId
  human.db.baowuLen = human.db.baowuLen + 1
  if human.db.baowuLen > 20 then
    human.db.baowuLen = 20
  end
  return data
end

function getYaoshu(human, id)
  for i=0, human.db.yaoshuListLen - 1 do
    if human.db.yaoshuList[i].id == id then
      return human.db.yaoshuList[i]
    end
  end
end

function addYaoshu(human, id)
  if getYaoshu(human, id) or not id then
    return
  end
  human.db.yaoshuList[human.db.yaoshuListLen].id = id
  human.db.yaoshuList[human.db.yaoshuListLen].skillLv = 1
  human.db.yaoshuList[human.db.yaoshuListLen].status = 1
  human.db.yaoshuListLen = human.db.yaoshuListLen + 1
  if human.db.yaoshuListLen > 20 then
    human.db.yaoshuListLen = 20
  end
end

function onDie(human, atker, utilityConfig)
    local hp = getHp(human)
    if hp>=1 then
        return
    elseif hp>0 then
        assert()
    end
    SceneEvent.do_ai_by_callback(human.scene_id, "on_player_die")
    Obj.stop(human)
    human.db.dieTime = os.time() 
    Buffer.onDie(human)
    Status.doHumanControlStatusChange(human, Status.HUMAN_STATUS_NORMAL)

    local map_id = Map.scene_id_to_map_id[human.scene_id]

    if atker and atker.isWorldBoss and 0 < atker.hp and 75 <= ExcelMonster.monster[atker.monster_id].lv and not checkIsInAvoidWar(human) and ExcelMapConf.scene[map_id].isPVP == 1 then
        ObjMonster.setHp(atker, atker.hp + ObjMonster.getHpMax(atker) / 10)
    end
    -- atker可能不是人，所以当有owner的时候，取拥有者
    if atker then
        atker = atker.owner and Obj.getOwner(atker) or atker
    end
    if atker and atker.obj_type == Obj.TYPE_HUMAN then
        local msg = Msg.lw.LW_SEND_KILLER
        msg.killUuid = atker._id
        Msg.send2world(msg, human._id)
    end

    if Copy.isCopyBySceneID(human.scene_id) then
        human.db.copyDieCount = (human.db.copyDieCount or 0) + 1
        CopyCallback.onRoleDieCB(atker, human)
    end
    Obj.sendGCObjDie(human, atker, utilityConfig)
    if atker.obj_type == Obj.TYPE_HUMAN and ExcelMapConf.scene[map_id].isPVP == 5 then
      local str = string.format(Lang.HUMAN_DIE_BY_HUMAN, HtmlUtil.fontName(atker.name, atker._id),ExcelMapConf.scene[map_id].name, HtmlUtil.fontName(human.name, human._id))
      Broadcast.sendBroadcast2World(Lang.UP + Lang.GROSSIP, str)
    end

    if atker and atker.obj_type == Obj.TYPE_HUMAN then
        Log.write(Log.LOGID_OSS_DIE, human._id, human.account, human.name, human.db.lv, atker.obj_type, atker.name, atker._id, human.db.map_id)
    elseif atker and atker.obj_type == Obj.TYPE_MONSTER then
        Log.write(Log.LOGID_OSS_DIE, human._id, human.account, human.name, human.db.lv, atker.obj_type, ObjMonster.getName(atker), atker.monster_id, human.db.map_id)
    elseif atker then
        Log.write(Log.LOGID_OSS_DIE, human._id, human.account, human.name, human.db.lv, atker.obj_type, "", "", human.db.map_id)
    else
        Log.write(Log.LOGID_OSS_DIE, human._id, human.account, human.name, human.db.lv, 0, "", "", human.db.map_id)
    end
end

function onLvUpCB(human, oldLv, newLv)
    if 1 <= human.db.hp then
        setHp(human, getHpMax(human))
    end
    setMp(human, getMpMax(human))

    local msgRet = Msg.gc.GC_LEVEL_UP
    msgRet.obj_id = human.id
    msgRet.lv = newLv
    local msgLw = Msg.lw.LW_LEVEL_UP
    msgLw.newLv = newLv 
    Msg.send2world(msgLw, human._id)
    TaskLogic.onLevelUp(human)
    ShenbingLogic.onLevelUp(human)
    doCalc(human)
    RoleUIControl.onLevelUp(human, oldLv, newLv)
    Obj.sendArea(msgRet, human.scene_id, human.x, human.y)  
    fuliHandler.onLvUp(human)
    PetLogic.sendPetList(human)
    BagHandlerL.AddSystemGift(human, oldLv, newLv)
    OfficialLogic.checkOneCondition(human, "roleLv")
    
    local sendMsg = Msg.gc.GC_LEVEL_UP_ADD_ATTR
    sendMsg.obj_id = human.id
    sendMsg.addAttr[0] = 0     
    RoleAttr.addAttrs(sendMsg.addAttr, RoleBaseAttr[newLv].addAttr)
    Msg.send(sendMsg, human.fd)
end

function addExp(human, addExp, worldExpAdd, type)
    if human.db.gm == 100 then return end -- 新手引导员不加经验

    if human.db.lv > #exp_conf then return end
    if not addExp then return end
    addExp = math.floor(addExp)
    if addExp == 0 then return end

    addExp, worldExpAdd = FcmLogic.handleExp(human, addExp, worldExpAdd)
    local total = human.db.exp + addExp
    if worldExpAdd then
        total = total + worldExpAdd
    end

    total = math.max(0, total)
    total = math.floor(total)

    if total == human.db.exp then
        return
    end

    local oldLv = human.db.lv
    human.db.exp = total
    local levelUp = checkLevelUp(human)

    local sum = addExp
    if worldExpAdd and worldExpAdd > 0 then
        sum = sum + worldExpAdd
        --		Broadcast.sendBroadcast(human, Lang.CHAT + Lang.NOT_COMPREHENSIVE, string.format(Lang.COMMON_GET_EXP_2, addExp, worldExpAdd))
    else
        --		Broadcast.sendBroadcast(human, Lang.CHAT + Lang.NOT_COMPREHENSIVE, string.format(Lang.COMMON_GET_EXP_1, addExp))
    end

    if levelUp == 1 then
        onLvUpCB(human, oldLv, human.db.lv)
    else
        human.attr[RoleDefine.EXP] = human.db.exp
        sendAttr(human,RoleDefine.EXP)
    end

    if not type then
        local msgRet = Msg.gc.GC_COMMON_ADD_EXP
        msgRet.levelUp = levelUp
        msgRet.exp = sum
        Msg.send(msgRet,human.fd)
    end

    return sum
end

function addAwake(human, addVal)
    if Cmds.passive.awake(human) then
        return false
    end
    human.db.awakeVal = human.db.awakeVal + addVal
    human.db.awakeVal = human.db.awakeVal <= 1000 and human.db.awakeVal or 1000
    human.attr[RoleDefine.AWAKE_VALUE] = human.db.awakeVal
    sendAttr(human,RoleDefine.AWAKE_VALUE)
end


function clearAwake(human)
    human.db.awakeVal = 0
    human.attr[RoleDefine.AWAKE_VALUE] = human.db.awakeVal
    sendAttr(human,RoleDefine.AWAKE_VALUE)
end

function setExp(human,value)
    if human.db.exp == value then return end
    local oldExp = human.db.exp
    human.db.exp = math.max(value,0)
    human.db.exp = math.min(value, exp_conf[human.db.lv].exp - 1)

    human.attr[RoleDefine.EXP] = human.db.exp
    sendAttr(human,RoleDefine.EXP)


    local msgRet = Msg.gc.GC_COMMON_ADD_EXP
    msgRet.levelUp = 0
    msgRet.exp = value - oldExp
    Msg.send(msgRet,human.fd)
end

function checkLevelUp(human)

    if human.db.lv > #exp_conf then
        return 0
    end

    local levelUp = 0
    while human.db.exp > 0 do
        local needExp = exp_conf[human.db.lv].exp
        if needExp <= human.db.exp then
            if human.db.lv >= #exp_conf then
                if human.db.exp > needExp then
                    human.db.exp = needExp
                end
                break
            else
                human.db.exp = human.db.exp - needExp
                incLv(human)
                levelUp = 1
            end
        else
            break
        end
    end
    return levelUp
end

function incLv(human)
    human.db.lv = human.db.lv + 1
    --升级日志
    Log.write(Log.LOGID_OSS_LEVELUP, human._id, human.account, human.name, human.ip, human.db.lv - 1, human.db.lv)

end

function getLv(human)
    return human.db.lv
end

function getName(human)
    return human.name
end

function sendHumanSet(human)
  local sendMsg = Msg.gc.GC_HUMAN_SET  
  sendMsg.reminder = human.db.humanSet
  Msg.send(sendMsg, human.fd) 
end

function sendAutoUseDrugPer(human)
  local sendMsg = Msg.gc.GC_HANG_SETTING  
  sendMsg.percent = human.db.autoUseDrugPer
  Msg.send(sendMsg, human.fd) 
end

function sendSkillItemList(human)
    local sendMsg = Msg.gc.GC_SEND_MEDICINE_SKILL
    for i = 0, 1 do
        sendMsg.skillItemList[i + 1] = human.db.skillItemList[i]
    end
    sendMsg.skillItemList[0] = 2 
    Msg.send(sendMsg, human.fd)
end

--技能等级
function getSkillLevelUp(human,skillID)
    local value = human.attr[RoleDefine.SKILL_LEVEL_UP] or 0
    if RoleExcel.skill2Attr[skillID] then
        local skillKey = RoleExcel.skill2Attr[skillID].attr
        return value + (human.attr[skillKey] or 0)
    end
    return value
end

--得到坐骑特效
function getHorseEffect(human)
  for i=1, #HorseExcel.stage do
    if HorseExcel.stage[i].horseId == human.db.chooseHorseId then
      return HorseExcel.stage[i].effect
    end
  end
  for k, v in pairs(HorseExcel.huanhua) do
    if k == human.db.chooseHorseId then
      return v.effect
    end
  end
  return 0
end

--形象
function getBodyInfo(human)
    -- sex equip
    local body = 0
    local bodyColor = 0
    local weapon = 0
    local weapon2 = 0
    local weaponEffect = 0
    local weapon2Effect = 0
    local bone = 0  -- 骨骼
    local pifeng = 0
    local horse = HorseLogic.getHorseSource(human)
    local baowuSource = 0
    local baowuEffect = 0  
    local head = 0
    local official = OfficialLogic.getOfficialImage(human)
    local leftarm = 0
    local rightarm = 0
    
    local sb = sbConfig[human.db.putonShenbing]
    local data = getShenbing(human, human.db.putonShenbing)    
    if sb and data then
       if data.jinhua == 0 then
          weapon = sb.weaponID[1]
          weaponEffect = data.star > 0 and sb.weaponEffect[1] or 0
          weapon2 = sb.weaponID2[1]
          weapon2Effect = data.star > 0 and sb.weaponEffect2[1] or 0
          bone =sb.boneID[1][human.db.sex]
       else
          weapon = sb.weaponID[2]
          weaponEffect = data.star>0 and sb.weaponEffect[2] or 0          
          weapon2 = sb.weaponID2[2]
          weapon2Effect = data.star>0 and sb.weaponEffect2[2] or 0
          bone =sb.boneID[2][human.db.sex]
       end
    else 
       sb = sbConfig[5]       
       if Buffer.hasBuf(human, 82) then
          weapon = 1
       end
    end
    local bodyGrid = human.db.equip[ItemDefine.CLOTH-1]
    local source
    if bodyGrid ~= nil and bodyGrid.id ~= 0 and EquipConf[bodyGrid.id] then
        source = EquipConf[bodyGrid.id].source[human.db.sex]       
    end
    if source == nil then
        source = human.db.sex
    end
    body = source

    if human.db.combatBaowu and human.db.combatBaowu ~= 0 then
      baowuSource, baowuEffect = BaowuLogic.getBaowuInfo(human, human.db.combatBaowu)
    end

    if human.db.curarmourid and human.db.curarmourid > 0 then
        head, body, pifeng, leftarm, rightarm = ArmourDefine.getViewInfo(human.db.curarmourid, human.db.sex)
    end

    if Cmds.passive.awake(human) then
        body = sb.awakeBodyID
        weapon = sb.awakeWeaponID
        weapon2 = sb.awakeWeaponID2
        bone = 0 --sb.awakeBoneID
        pifeng = 0
        horse = 0
        return body,weapon,weaponEffect,pifeng,horse,bone,weapon2,weapon2Effect,0,getHorseEffect(human),bodyColor, baowuSource, baowuEffect
    end
    if Copy.isCopy(Map.scene_id_to_map_id[human.scene_id]) == CopyDefine.COPY_DATI_ID then
        horse = 0
    end
    return body,weapon,weaponEffect,pifeng,horse,bone,weapon2,weapon2Effect,0,getHorseEffect(human),bodyColor, baowuSource, baowuEffect, head, official, leftarm, rightarm
end

function humanHpRecover()
    -- 生命自然回复量 = 生命值上限 × 0.04
    for k,v in pairs(onlineHuman) do
        HorseLogic.setHuanhuaRemainTime(v)
        PetLogic.checkLimtPet(v)
        BaowuLogic.checkLimtBaowu(v)
        MonthCardLogic.checkMonthCardExpire(v)
        if v.scene_id and v.db.hp >0 then
            setHp(v,v.db.hp + getHpMax(v) * BaseAttrInitValue.hp_recover)
        end
    end
end

mptimer = mptimer or 0
function human1second()
    mptimer = mptimer + 1
    mptimer = mptimer%4
    for name, human in pairs(onlineHuman) do
        if human.scene_id and human.db.hp >0 then
            setMp(human, human.db.mp + getAttr(human, RoleDefine.MP_RECOVER)) -- 每秒回蓝
            addJumpValue(human, BaseAttrInitValue.jump_recover)			          -- 每秒加跳跃值           
            if mptimer == 0 then
                sendAreaHpMp(human)
            end
        end
        human.db.onLineSeconds = human.db.onLineSeconds + 1
    end
end

--属性逻辑
function getAttr(human, key)
    return human.attr[key]
end

function getRadius()
    return 50
end



local old_attr = {}
function doCalc(human)
    for k in pairs(old_attr) do
        old_attr[k] = nil
    end
    for k, v in pairs(human.attr) do
        old_attr[k] = v
    end
    human.killMonsterExpAddValue = nil
    human.killMonsterExpAddRate = nil
    
    RoleAttr.doCalc(human)
    local mm = Msg.gc.GC_ROLE_ATTR
    local len = 0
    local left = mm.attrs
    local isZDLChange
    local isHpMpChange 
    for k,v in pairs(human.attr) do
        if type(v) == "number" and v ~= old_attr[k] then
            len = len + 1
            left[len].key = k
            left[len].value = v

            if k == RoleDefine.ZHANDOULI then
                isZDLChange = true
            end
            if not isHpMpChange and (k == RoleDefine.HP_MAX or k == RoleDefine.MP_MAX or k == RoleDefine.HP or k == RoleDefine.MP )then
                isHpMpChange = true
            end
        end
    end
    if 0 < len then
        left[0] = len
        Msg.send(mm, human.fd)
    end
    
    if isHpMpChange then
       sendAllAttr(human)
    end
end

function sendAllAttr(human)
    local mm = Msg.gc.GC_ROLE_ATTR
    local len = 0
    local left = mm.attrs
    for k,v in pairs(human.attr) do
        if type(v) == "number" then
            len = len + 1
            left[len].key = k
            left[len].value = v
        end
    end
    left[0] = len
    Msg.send(mm, human.fd)
end

function sendAreaHpMp(human)
  if not human.scene_id or human.hide then
      return
  end
  local mm = Msg.gc.GC_OBJ_HP
  mm.obj_id = human.id
  mm.hp = human.db.hp
  mm.hp_max = getHpMax(human)
  mm.mp = human.db.mp
  mm.mp_max = getMpMax(human)
  Obj.sendArea(mm, human.scene_id, human.x, human.y, human.fd)
end

function onBeHit(attacker,human,shanghai)
    if shanghai>0 then
        --Utilitys.equipCallSkill(human,attacker,SkillDefine.EQUIP_CALL_SKILL_CONDITION_BE_HIT,attacker.x,attacker.y)
        local isSame = attacker.id == human.id --有些buf会导致自己打自己
        if attacker then
            if attacker.obj_type == Obj.TYPE_HUMAN and not isSame then
                attacker.laskSkillTime = os.time()	-- 最近一次打人
                human.laskBeHitTime = os.time()	-- 最近一次被打
                
--                if canAddAwake(human) then   --被打，加觉醒值20
--                    addAwake(human, 20)
--                end
--                if canAddAwake(attacker) then --打人，加觉醒值10
--                    addAwake(attacker, 10)
--                end
                CopyCallback.onRoleBeHitCB(attacker,human,shanghai)
            end
            PetAi.onOwnerBeHit(attacker, human)            
        end
    end
end

function onSkill(human, x, y, skillID)
    local config = SkillConfig[skillID]
    if config.actionID[1]~=-1 then
        if human.path_len > 0 then
            if Timer.last_exe_time.walk and Timer.now - Timer.last_exe_time.walk > Timer.register_timer.walk / 2 then
                Obj.stop(human)
            else
                if Obj.checkClientPos(human, x, y) == true then
                    human.path_len = 0
                    human.path_client_x = x
                    human.path_client_y = y
                    human.path_time = Timer.now
                else
                    Obj.resetPathParam(human)
                end
            end
        end
    end
end

-- 判断是否战斗状态
function checkIsInFighting(human,duration)
    local nowTime = os.time()
    local tempTime = duration or 7
    if human.laskSkillTime and nowTime - human.laskSkillTime < tempTime then
        human.db.fight = 1
        return true
    end
    if human.laskBeHitTime and nowTime - human.laskBeHitTime < tempTime then
        human.db.fight = 1
        return true
    end
    human.db.fight = 0
end
function resetFightSec(human)
    human.laskSkillTime = nil
    human.laskBeHitTime = nil
    human.db.fight = 0
end
function checkFightSec(human,duration)
    if not duration then return -1 end
    local nowTime = os.time()
    local tempTime1 = human.laskSkillTime and nowTime - human.laskSkillTime or duration
    local tempTime2 = human.laskBeHitTime and nowTime - human.laskBeHitTime or duration
    local tempTime =  tempTime1 > tempTime2 and tempTime2 or tempTime1
    return duration-tempTime
end

-- 判断是否免战模式
function checkIsInAvoidWar()
    
end

-- 音效
function sendSoundEffect(id, human, x,y,area)
    local msg = Msg.gc.GC_SOUND_EFFECT
    msg.id = id
    if area then
        Obj.sendArea(msg, human, x, y)
    else
        Msg.send(msg, human.fd)
    end
end



--玩家跨天登陆接口
function humanLoginCrossDay( human )
    updateDaily(human)
end

--玩家跨天的时候在线
function humanOnlineCrossDay( human )
    updateDaily(human)
    
    RoleUIControl.sendLine1FnIcon(human)
    RoleUIControl.sendPreknow(human)
end

-- 检查玩家的创角时间是不是大于N天
-- 特别的很久以前的玩家没有创角时间，直接返回false
function checkCreateTimeOverDay(human, day)
    if human.db.createTime == nil then
        return false
    end

    local createDay = Util.diffDay(human.db.createTime)
    if createDay >= day then
        return true
    end

    return false
end

function updateDaily(human, isGm)
    if not isGm then
      if human.db.update_daily_time ~= 0 and Util.isSameDay(human.db.update_daily_time) then
        return
      end
    end
    -- todo	ResourceRecover.refresh(human)	--	需记录前一天的信息
    
    local diffDay = Util.diffDay(human.db.update_daily_time) > 3 and 3 or Util.diffDay(human.db.update_daily_time)
    if human.db.update_daily_time ~= 0 then
      for j=1, diffDay do
        for i=0, human.db.copyFindLen - 1 do
          human.db.copyFind[i].copyYestdayFreeFindTimes = human.db.copyFind[i].copyFreeFindTimes      
          human.db.copyFind[i].copyYestdayYuanbaoFindTimes = human.db.copyFind[i].copyYuanbaoFindTimes
        end
        for i=0, human.db.ActFindLen - 1 do
          human.db.ActFind[i].actYestdayFindType = human.db.ActFind[i].actFindType
          human.db.ActFind[i].actYuanbaoYestdayFindType = human.db.ActFind[i].actYuanbaoFindType  
        end
        if diffDay > 1 and j > 1 then
          FindResLogic.clearCurStatus(human)          
          FindResLogic.sendActFind(human, nil, true)
          FindResLogic.sendCopyFind(human, nil, true)
        else
          FindResLogic.sendActFind(human, true)
          FindResLogic.sendCopyFind(human, true)
        end 
      end
    end
    human.db.loginKeepDay = human.db.loginKeepDay + 1 --累计登陆天数+1
    human.db.onLineSeconds = 0
    human.db.copyTimesLen = 0   --副本次数清空
    human.db.pata_reset = 0     --pata重置次数
    human.db.pata_ko = 0        --pata扫荡次数
    human.db.pata_add = 0
    human.db.actValue = 0        -- 活跃度
    human.db.actValueRecordLen = 0
    human.db.actValueRewardOk = 0
    
    FirstPayLogic.updateDaily(human)
  
    
    TaskLogic.updateDaily(human)   --任务
    if human.db.rmbSmeltIsPut == 1 then
      human.db.yestdaySmeltTimes = human.db.rmbSmeltTimes
    end
    human.db.rmbSmeltTimes = 0 --元宝熔炼次数
    human.db.rmbSmelthelpTimes = 0 --元宝熔炼帮助他人次数
    fuliHandler.updateStatus(human) --福利大厅重置
    MonthCardLogic.setStatus(human) --月卡奖励重置
    human.db.worshipLen = 0 --膜拜次数重置   
    
    human.db.item_use_cntLen = 0    --每天使用道具次数
    human.db.item_use_groupLen = 0  --每天道具使用组可使用次数
    WushuangCopy.setTZValue(human)
    human.db.dailyChongzhi = 0 --每日充值清零
    human.db.dailyCostBindYunabao = 0 --每日消费的绑定元宝
    human.db.openActDrawTimes = 0 --开服活动抽奖次数
    
--    SmeltLogic.sendSmeltTimes(human)
--    SmeltLogic.sendIsPut(human)
--    SmeltLogic.sendRemainHelpTimes(human)
        
    MySteryShop.OnDayChange(human)
    FamilyHandlerL.CG_FAMILY_SHOP_QUERY(human, true)
    ShopLogic.clearStatus(human)     
    YellowLogic.clearStatus(human)
    BlueLogic.clearStatus(human)
    TGPLogic.clearDailyStatus(human)
    human.db.riotFamilyExp = 0
    human.db.riotContribution = 0    
    human.db.offlinePkRewardRank = human.db.offlinePkRank --离线PK
    OperateActLogicL.clearStatus(human)
    human.attr[RoleDefine.DAILY_CHONGZHI] = human.db.dailyChongzhi
    sendAttr(human,RoleDefine.DAILY_CHONGZHI)
    human.db.dailyCostYuanbao = 0
    human.attr[RoleDefine.DAILY_COST_YUANBAO] = human.db.dailyCostYuanbao
    sendAttr(human,RoleDefine.DAILY_COST_YUANBAO)
    for i=0, 9 do
      human.db.YYPayDrawStatus[i] = 0
    end
    for i=0, 9 do
      human.db.DateChongzhiRebate[i] = 0
    end
    
    if -1 == DateActFL.onGetCurActRuleID(AcvityDefine.OPERATEACT_TYPE_LIMITBUY) or DateActFL.onGetCurActVersion(AcvityDefine.OPERATEACT_TYPE_LIMITBUY) ~= human.db.DateActivityId[AcvityDefine.OPERATEACT_TYPE_LIMITBUY] then
      for i=0, 39 do
        human.db.DateLimitBuyTimes[i - 1] = 0
      end
      DateLimitBuy.open(human, AcvityDefine.OPERATEACT_TYPE_LIMITBUY)
    end
    human.db.DateCritDrawTimes = 0
    for i=0, 9 do
      human.db.DatePayDrawStatus[i] = 0
    end
    human.db.DatePayDrawTimes = 0
    human.db.YYChongzhiDrawTimes = 0
    if not Util.isSameWeek(os.time(), human.db.update_daily_time) then
      human.db.tgpWeek = 0
    end
    human.db.update_daily_time = os.time()
    human.db.familyOnHookTime = 0
    human.db.familyOnHookBuyTime = 0
    human.db.familyAlgContributionRmb = 0
    human.db.officialRewardIsGet = 1
    
    human.db.wsslTime = 0 --武圣试炼时间
    
    human.db.ChongzhiPresentCnt = 0 --充值豪礼领取次数
    
    for i = 0, 5 do   --3366
      human.db.level3366CanGet[i] = 0
    end
    
    DailyGift.updateDaily(human) -- 每日豪礼刷新
end
